<template lang="pug">
  div.vw.active(v-if="isVisible")
    div.tt
      | 准备采集图像，请点击
      span(@click="onPhotograph") 【确定】
      | 按钮，并目视摄像头。
    div.video-w
      video#video.video(:width="videoWidth" :height="videoHeight")
      div.video-mk(ref="videoMk" :class="{'active':isMk}")
      canvas#canvas.canvas(:width="photoWidth" :height="photoHeight")
    div
      div.btn-confirm(@click="onPhotograph") 确定
    div.div-time(v-if="isShowTimer") {{strTimer}}


</template>

<script type="text/ecmascript-6">
  import fs from 'fs'
  import Ftp from 'ftp'

  export default {
    props: {
      /**
       * 照片宽度
       */
      photoWidth: {
        type: Number,
        default: 567
      },
      /**
       * 照片高度
       */
      photoHeight: {
        type: Number,
        default: 390
      },
      photoSavePath: {
        type: String,
        default: `${__static}\\photo\\`
      },
      photoSaveName: String
    },
    data() {
      return {
        videoWidth: 800,
        videoHeight: 600,
        cameraState: false,
        smallVideo: null,
        stream: null,
        isVisible: false,
        fileName: '',
        strTimer: 3,
        timerMt: null,
        isShowTimer: false,
        isMk: false
      }
    },
    mounted() {
      this.$nextTick(() => {
        const body = document.querySelector(`body`)
        if (body.append) {
          body.append(this.$el)
        } else {
          body.appendChild(this.$el)
        }
      })
    },
    methods: {
      async onPhotograph() {
        if (!this.cameraState) {
          this.handlerConnectCamera()
        }
        this.isShowTimer = true
        this.strTimer = 3
        await this.jishiSync()
        this.isMk = true
        this.canvas = document.querySelector('canvas')
        let context = this.canvas.getContext('2d')
        if (this.smallVideo) {
          context.drawImage(this.smallVideo, 0, 0, this.photoWidth, this.photoHeight)
          this.handlerSaveImg(this.fileName)
        }
      },
      jishiSync() {
        return new Promise(resolve => {
          this.timerMt = setInterval(() => {
            this.strTimer -= 1
            if (this.strTimer <= 0) {
              this.isShowTimer = false
              clearInterval(this.timerMt)
              resolve()
            }
          }, 1000)
        })
      },
      /**
       * 打开照相机
       * @returns {Promise<void>}
       */
      async handlerConnectCamera() {
        console.log('navigator.mediaDevices:', navigator.mediaDevices)
        try {
          let _stream = await navigator.mediaDevices.getUserMedia({
            video: {
              width: this.videoWidth,
              height: this.videoHeight
            },
            audio: false
          })
          console.log('_stream:', _stream)
          this.cameraState = true
          this.stream = _stream.getTracks()[0]
          this.smallVideo = document.querySelector('video')
          this.smallVideo.src = (window.URL || window.webkitURL).createObjectURL(_stream)
          this.smallVideo.play()
        } catch (e) {
          this.$alert('没有检查到摄像头！', '消息')
        }
      },
      /**
       * 关闭照相机
       */
      handlerCloseCamera() {
        this.isVisible = false
        this.cameraState = false
        this.stream && this.stream.stop()
      },
      /**
       * 拍照
       */
      handlerPhotograph(_fileName) {
        this.fileName = _fileName
        return new Promise(resolve => {
          this.isVisible = true
          this.$nextTick(() => {
            this.$refs.videoMk.addEventListener(`webkitAnimationEnd`, () => {
              this.isMk = false
            })
            this.handlerConnectCamera()
          })
        })
      },
      /**
       * 保存照片
       */
      async handlerSaveImg(_fileName) {
        let data = this.canvas.toDataURL('image/png', 1)
        let fileName = _fileName || this.photoSaveName || Date.now()
        this.filePath = this.photoSavePath + `${fileName}.png`
        let base64 = data.replace(/^data:image\/\w+;base64,/, '')
        let dataBuffer = Buffer.alloc(base64.length, base64, 'base64')
        let err = fs.writeFileSync(this.filePath, dataBuffer)
        if (err) {
          console.log(err)
        } else {
          console.log('写入成功！')
        }
        // this.handlerCloseCamera()
        await this.uploadFtp(_fileName)
        this.$emit('photographed')
      },
      uploadFtp(_fileName) {
        return new Promise(resolve => {
          let c = new Ftp()
          c.on('ready', () => {
            c.put(this.filePath, `\\photo\\${_fileName}.png`, err => {
              if (err) {
                console.log('_uploadFile err', err)
              }
              c.end()
              resolve(err)
            })
          })
          c.connect({
            host: window.KalixConfig.ftphost,
            user: window.KalixConfig.ftpuser,
            password: window.KalixConfig.ftppwd
          })
          c.on('error', (err) => {
            resolve(err)
          })
        })
      }
    }
  }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  .vw
    position fixed
    display none
    top -1000px
    left -10000px
    height 0
    width 0
    overflow hidden
    z-index -1
    background-color rgba(255, 255, 255, 1)
    text-align center

    &.active
      display block
      top 0
      left 0
      right 0
      bottom 0
      height 100%
      width 100%
      z-index 999

    .tt
      line-height 42px
      height 42px
      font-size 16px
      border-bottom 1px solid #c0c0c0
      color #333333
      user-select none
      cursor default

      span
        color #0454bb
        cursor pointer

        &:hover
          text-decoration underline

    .btn-confirm
      display inline-block
      height 60px
      border-radius 50%
      line-height 60px
      box-sizing content-box
      box-shadow 0 0 15px 2px #000000
      cursor pointer
      width 60px

    .video-w
      position relative
      height 600px
      padding 20px 0
      box-sizing content-box

    .video
      position absolute
      left 50%
      margin-left -400px
      box-shadow 0 0 10px rgba(0, 0, 0, .8)

    .video-mk
      width 800px
      height 600px
      position absolute
      left 50%
      margin-left -400px
      background-color rgba(255, 255, 255, .8)
      opacity 0

      &.active
        animation fl .2s ease-in-out

    .canvas
      display none
      z-index -1

    .div-time
      position absolute
      z-index 9
      background-color rgba(255, 255, 255, .5)
      width 100%
      height 100%
      top 0
      left 0
      text-align center
      line-height 800px
      font-size 600px
      color rgba(255, 255, 255, 1)
      text-shadow 1px 1px 5px #000, 1px 0 5px #000, 0 0 5px #000, 0 1px 5px #000

  @keyframes fl
    0%, 100%
      opacity 0
    50%
      opacity 1
</style>
